/*
 * Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
 * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
 * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
 * Vestibulum commodo. Ut rhoncus gravida arcu.
 */

package com.mrd.spring.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.NameFilter;
import com.alibaba.fastjson.serializer.PropertyFilter;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.mrd.framework.config.web.json.JsonFastJsonHttpMessageConverter;
import com.mrd.framework.config.web.json.filter.JsonPropertyFilter;

import org.springframework.data.domain.Page;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

/**
 * 继承 JsonFastJsonHttpMessageConverter 解决JPA分页问题
 * Created by dengdc on 2017/8/25.
 */
public class CustomFastJsonHttpMessageConverter extends JsonFastJsonHttpMessageConverter {
    private static final String[] pageProperties = { "first", "last", "number", "numberOfElements", "size", "sort", "totalElements", "totalPages"};
    static {

    }

    public CustomFastJsonHttpMessageConverter() {
    }

    protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException,
            HttpMessageNotWritableException {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        Method method = (Method)request.getAttribute("$_json_execute_method___");
        if(method != null && obj != null) {
            PropertyFilter propertyFilter = JsonPropertyFilter.create(method, obj.getClass());
            SerializeFilter[] filters;
            if(Page.class.isAssignableFrom(obj.getClass())) {
                //拓展Page类型转译成Json时输出的属性
                try {
                    Field includeProps = JsonPropertyFilter.class.getDeclaredField("includeProperties");
                    includeProps.setAccessible(true); //打开访问
                    Set<String> props = (Set<String>) includeProps.get(propertyFilter);
                    props.addAll(Arrays.asList(pageProperties));
                    includeProps.setAccessible(false); //使用完后关闭访问
                } catch (NoSuchFieldException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            filters = new SerializeFilter[]{propertyFilter};

            OutputStream out = outputMessage.getBody();
            String text = JSON.toJSONString(obj, filters, new SerializerFeature[]{SerializerFeature.DisableCircularReferenceDetect});
            byte[] bytes = text.getBytes(super.getCharset());
            out.write(bytes);
        } else {
            super.writeInternal(obj, outputMessage);
        }

        request.removeAttribute("$_json_execute_method___");
    }
}
